﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml;

namespace VivendoByteToolkit.Helpers
{
    public class FocusCommandHelper
    {
        #region Got Focus
        public static ICommand GetGot(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(GotProperty);
        }

        public static void SetGot(DependencyObject obj, ICommand value)
        {
            obj.SetValue(GotProperty, value);
        }

        public static readonly DependencyProperty GotProperty =
            DependencyProperty.RegisterAttached("Got",
            typeof(ICommand),
            typeof(FocusCommandHelper),
            new PropertyMetadata(null,
            new PropertyChangedCallback(SetupGotFocus))); 
        #endregion

        #region Lost Focus
        public static ICommand GetLost(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(LostProperty);
        }

        public static void SetLost(DependencyObject obj, ICommand value)
        {
            obj.SetValue(LostProperty, value);
        }

        public static readonly DependencyProperty LostProperty =
            DependencyProperty.RegisterAttached("Lost",
            typeof(ICommand),
            typeof(FocusCommandHelper),
            new PropertyMetadata(null,
            new PropertyChangedCallback(SetupLostFocus)));
        #endregion

        private static void SetupGotFocus(DependencyObject obj,
            DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement ctl = obj as FrameworkElement;

            if (ctl != null)
            {
                ICommand oldValue = (ICommand)e.OldValue;
                ICommand newValue = (ICommand)e.NewValue;

                if (oldValue == null && newValue != null)
                {
                    ctl.GotFocus += ctl_GotFocus;
                }
                else if (oldValue != null && newValue == null)
                {
                    ctl.GotFocus -= ctl_GotFocus;
                }
            }
        }

        private static void SetupLostFocus(DependencyObject obj,
            DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement ctl = obj as FrameworkElement;

            if (ctl != null)
            {
                ICommand oldValue = (ICommand)e.OldValue;
                ICommand newValue = (ICommand)e.NewValue;

                if (oldValue == null && newValue != null)
                {
                    ctl.LostFocus += ctl_LostFocus;
                }
                else if (oldValue != null && newValue == null)
                {
                    ctl.LostFocus -= ctl_LostFocus;
                }
            }
        }

        static void ctl_LostFocus(object sender, RoutedEventArgs e)
        {
            var element = sender as FrameworkElement;
            var command = GetLost(element);

            if (command != null)
            {
                if (command.CanExecute(null))
                {
                    command.Execute(null);
                }
            }
        }

        static void ctl_GotFocus(object sender, RoutedEventArgs e)
        {
            var element = sender as FrameworkElement;
            var command = GetGot(element);

            if (command != null)
            {
                if (command.CanExecute(null))
                {
                    command.Execute(null);
                }
            }
        }
    }
}